/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package jturbofile.net;

import java.awt.TrayIcon.MessageType;
import java.net.*;
import java.io.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import jturbofile.Config;
import jturbofile.gui.ConnectedUserUI;
import jturbofile.gui.JTurboFileGUI;
import jturbofile.gui.LogPanel;
import jturbofile.gui.TrayGUI;

/**
 *
 * @author Rolf
 */
public class NetCore implements Runnable {
    private static NetCore singleton;
    
    private ServerSocket server;
    private Map<String, PeerThread> peers;
    private int port;
    
    public static void startNetCore(int port) {
        if( singleton == null ) {
            singleton = new NetCore(port);
        }
    }
    
    public static NetCore singleton() {
        return singleton;
    }
    
    private NetCore(int port) {
        this.port = port;
        peers = new HashMap<String, PeerThread>();
        
        try {
            server = new ServerSocket(port);
            
            new Thread(this).start();
            
            LogPanel.singleton().logln("NetCore started on port ["+port+"]");
        }
        catch(Exception e) {
            LogPanel.singleton().logln("Error creating socket: "+e);
        }
    }
    
    public void run() {
        while(true) {
            try {
                Socket s = server.accept();
                
                if( s.getInetAddress().getHostAddress().equals(s.getLocalAddress().getHostAddress()) ) {
                    LogPanel.singleton().logln("Cant connect to self!");
                }
                else {
                
                    LogPanel.singleton().logln("Peer connected ["+s.getInetAddress().getHostAddress()+"]...");

                    PeerThread pt = new PeerThread(s);

                    String key = generateKey(s);

                    if( !peers.containsKey(key) ) {
                        peers.put(key, pt);
                        new Thread(pt).start();
                        
                        TrayGUI.singleton().displayMessage("New peer", "A new peer connected ["+s+"]", MessageType.INFO);
                        JTurboFileGUI.singleton().updateUsers();
                    }
                    else {
                        LogPanel.singleton().logln("Already connected to ["+s.getInetAddress().getHostAddress()+"]");
                    }
                }
            }
            catch (IOException e) {
                LogPanel.singleton().logln("Exception with socket connection: "+e);
            }
        }
    }

    public void removePeerThread(Socket s) {
        peers.remove(generateKey(s));
        
        LogPanel.singleton().logln("Connection closed ["+s.getInetAddress().getHostAddress()+"]...");
        
        JTurboFileGUI.singleton().updateUsers();
    }
    
    public String generateKey(Socket s) {
        return s.getInetAddress().getHostAddress();
    }
    
    public void connectToPeer(String addr) {
        connectToPeer(addr, port);
    }
    
    public void connectToPeer(String addr, int port) {
        new Thread(new ConnectThread(addr, port)).start();
    }
    
    public void sendFiles(List<File> files, PeerThread pt, ConnectedUserUI userUI) {
        new Thread(new SendFileThread(files, pt, userUI)).start();
    }
    
    public Map<String, PeerThread> getPeers() {
        return peers;
    }
}
